#include <dos/exall.h>

typedef struct
{    char mem[4096];
     BPTR lock;
     struct FileInfoBlock *fib;
     struct ExAllData *ead;
     struct ExAllControl *eac;
     Att_Node *dirnode;
     Att_Node *remnode;
     Att_List *dirlist;
     char string[256];
} Combi;


// the argument "entrylist" must be already intialized.
// you will get the results in this list... 

BOOL Recurse( Att_List *entrylist ) // needs for me for 40MB 2 mins...
{     
     Combi *combi;
     
     BOOL ret = TRUE; 
     
     if( (combi = AllocMemH(mempool, sizeof(Combi))) )
       {
          if( (combi->fib = AllocDosObject(DOS_FIB, NULL)) )
            {
               if( (combi->eac = AllocDosObject(DOS_EXALLCONTROL, NULL)) )
                 {
                    combi->dirlist = Att_NewList( LISTF_POOL );
                    combi->dirnode = (Att_Node *) entrylist->list.lh_Head;
                    
                    while( combi->dirnode->node.ln_Succ )
                      {
                         combi->lock = Lock( combi->dirnode->node.ln_Name, SHARED_LOCK );
          
                         Examine( combi->lock, combi->fib );
                         
                         UnLock( combi->lock );
           
                         if( combi->fib->fib_DirEntryType > 0 )
                           {
                              Att_NewNode( combi->dirlist, combi->dirnode->node.ln_Name, NULL, NULL );
                              
                              if( combi->dirnode->data )
                                   FreeMemH( (APTR) combi->dirnode->data );
                                   
                              combi->dirnode = (Att_Node *) (combi->remnode = combi->dirnode)->node.ln_Succ;
               
                              Att_RemNode( combi->remnode );
                               
                           }
                         else 
                              combi->dirnode = (Att_Node *) combi->dirnode->node.ln_Succ;
                      }
             
                    while( (combi->dirnode = (APTR) combi->dirlist->list.lh_Head)->node.ln_Succ )
                      {
                         combi->lock = Lock( combi->dirnode->node.ln_Name, SHARED_LOCK );
                         combi->eac->eac_LastKey = 0;
                          
                         do
                           {
                              combi->ead = (APTR) combi->mem;
                                                                                
                              if( (!(ret = ExAll(combi->lock, combi->ead, 4096, ED_TYPE, combi->eac)) &&
                                   IoErr() != ERROR_NO_MORE_ENTRIES) )
                                   break;
                                                                                          
                              if( !combi->eac->eac_Entries )
                                   continue;
                               
                              do
                                {
                                   strcpy( combi->string, combi->dirnode->node.ln_Name );
                                   AddPart( combi->string, combi->ead->ed_Name, 256 );
                                   Att_NewNode( combi->ead->ed_Type < 0 ? entrylist : combi->dirlist, combi->string, NULL, ADDNODEF_EXCLUSIVE );
                                }
                              while( (combi->ead = combi->ead->ed_Next) );
                           }
                         while( ret );
          
                         UnLock( combi->lock );
                         Att_RemNode( combi->dirnode ); 
                      }
                      
                    Att_RemList( combi->dirlist, NULL );
                                        
                    FreeDosObject( DOS_EXALLCONTROL, combi->eac );
                 }
               FreeDosObject( DOS_FIB, combi->fib );
            }
          FreeMemH( combi );
       }
     return ret;
}